package net.jjjshop.common.util;

import cn.hutool.core.lang.Assert;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.regex.Pattern;

/**
 * 天翼云媒体存储
 */
@Slf4j
public class OssUtils {
    private static final String accessKey = "brDKfCd1nvJ6s8IFGVAD";
    private static final String secretKey = "FPsNrJQItcuvVNPSh51j4LEoD49RO2erC6y7pTeV ";
    private static final String endPoint = "cq4oss.ctyunxs.cn";
    @Getter
    private static final String bucketName = "nownc178";
    @Getter
    private static final String url_prefix = "https://nownc178.cq4oss.ctyunxs.cn/";
    private static final AmazonS3 s3;

    static {
        BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
        ClientConfiguration clientConfiguration = new ClientConfiguration();
        AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(
                endPoint, Regions.DEFAULT_REGION.getName());
        s3 = AmazonS3ClientBuilder.standard()
                //客户端设置
                .withClientConfiguration(clientConfiguration)
                //凭证设置
                .withCredentials(new AWSStaticCredentialsProvider(credentials))
                //endpoint设置
                .withEndpointConfiguration(endpointConfiguration)
                .build();
    }

    /**
     * 上传文件
     *
     * @return 对象键
     */
    public static List<String> uploadFile(List<MultipartFile> files) {
        Assert.notEmpty(files, "文件为空");
        ArrayList<String> objKeys = new ArrayList<>();
        for (MultipartFile file : files) {
            FileInputStream is = convertMultipartFileToFileInputStream(file);
            try {
                ObjectMetadata meta = new ObjectMetadata();
                meta.setContentLength(is.available());
                // 获取文件原名称
                String filename = file.getOriginalFilename();
                // 判断文件类型
                String fileType = judgeFileType(Objects.requireNonNull(filename));
                // 生成objectKey
                String objectKey = fileType + "/" + UUID.randomUUID() + filename;
                PutObjectRequest req = new PutObjectRequest(bucketName, objectKey, is, meta);
                s3.putObject(req);
                log.info("文件上传成功==》{}", objectKey);
                objKeys.add(objectKey);
            } catch (AmazonServiceException e) {
                log.error(e.getErrorMessage());
            } catch (Exception e) {
                log.error("文件上传异常:{}", e.getMessage(), e);
            }
        }
        return objKeys;
    }

    /**
     * 上传单个文件
     *
     * @param file      文件
     * @param objectKey 键
     * @return
     */
    public static String uploadFile(File file, String objectKey) {
        try {
            FileInputStream is = new FileInputStream(file);
            ObjectMetadata meta = new ObjectMetadata();
            meta.setContentLength(is.available());
            PutObjectRequest req = new PutObjectRequest(bucketName, objectKey, is, meta);
            s3.putObject(req);
            log.info("文件上传成功==》{}", objectKey);
        } catch (AmazonServiceException e) {
            log.error(e.getErrorMessage());
        } catch (Exception e) {
            log.error("文件上传异常:{}", e.getMessage(), e);
        }
        return objectKey;
    }

    /**
     * 下载文件
     *
     * @param objectKey
     * @param localPath 下载路径如：C:\Users\admin\Desktop\
     */
    public static void downloadFile(String objectKey, String localPath) {
        try {
            GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, objectKey);
            S3Object o = s3.getObject(getObjectRequest);
            S3ObjectInputStream s3is = o.getObjectContent();
            // 生成文件名包含文件路径
            String filename = localPath + objectKey.replace("/", "");
            FileOutputStream fos = new FileOutputStream(filename);
            byte[] read_buf = new byte[1024];
            int read_len = 0;
            while ((read_len = s3is.read(read_buf)) > 0) {
                fos.write(read_buf, 0, read_len);
            }
            s3is.close();
            fos.close();
            log.info("下载完成，路径====>{}", filename);
        } catch (IOException e) {
            log.error("文件下载失败:{}", e.getMessage(), e);
        }
    }

    /**
     * 判断文件类型
     */
    public static String judgeFileType(String fileName) {
        String lowerCaseFileName = fileName.toLowerCase();
        String imgRegex = ".*\\.(jpg|jpeg|png|gif|bmp)$";
        String mp3Regex = ".*\\.(mp3|wav|ogg|flac)$";
        String videoRegex = ".*\\.(mp4|avi|mkv|flv|mov|wmv)$";

        if (Pattern.matches(imgRegex, fileName.toLowerCase())) {
            return "img";
        } else if (Pattern.matches(mp3Regex, fileName.toLowerCase())) {
            return "mp3";
        } else if (Pattern.matches(videoRegex, lowerCaseFileName)) {
            return "mp4";
        } else {
            return "otherType";
        }
    }

    /**
     * 转化为文件流
     */
    public static FileInputStream convertMultipartFileToFileInputStream(MultipartFile multipartFile) {
        // 将 MultipartFile 保存到服务器的临时目录中
        File tempFile = null;
        try {
            tempFile = File.createTempFile("temp", null);
            multipartFile.transferTo(tempFile);
            // 创建 FileInputStream 对象并返回
            return new FileInputStream(tempFile);
        } catch (IOException e) {
            log.error("文件下载失败:{}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 获取文件访问地址
     *
     * @param objKey
     * @return
     */
    public static String getUrl(String objKey) {
        if (objKey==null || objKey.startsWith("http")){
            return objKey;
        }
        return url_prefix + objKey;
    }

}
